#include "StrBlob.h"
#include <memory>
#include <string>
#include <stdexcept>
/**
 * @brief 对于访问一个不存在元素的尝试， StrBlob 抛出一个异常
 * 
 */
class StrBlobPtr
{
private:
    // 若检查成功，check 返回一个指向 vector 的 shared_ptr
    std::shared_ptr<std::vector<std::string>> check(std::size_t, const std::string&) const;
    // 保存一个 weak_ptr,意味着底层 vector 可能会被销毁
    std::weak_ptr<std::vector<std::string>> wptr;
    // 在数组中的当前位置
    std::size_t curr;
public:
    StrBlobPtr() : curr(0) { }
    StrBlobPtr(StrBlob &a, size_t sz = 0) : wptr(a.data), curr(sz) { } 
    std::string& deref() const;
    // 前缀递增
    StrBlobPtr& incr(); 
};
/**
 * @brief 
 * 
 * @param i 
 * @param msg 
 * @return std::shared_ptr<std::vector<std::string>> 
 */
std::shared_ptr<std::vector<std::string>> StrBlobPtr::check(std::size_t i, const std::string &msg) const
{
    auto ret = wptr.lock(); // vector 还存在么
    if(!ret)
    {
        throw std::runtime_error("unbound StrBlobPtr");
    }
    if(i >= ret->size())
    {
        throw std::out_of_range(msg);
    }
    return ret; // 返回指向vector 的shared_ptr
}
/**
 * @brief 
 * 
 * @return std::string& 
 */
std::string& StrBlobPtr::deref() const
{
    auto p = check(curr, "dereference past end");
    return (*p)[curr]; // (*p)是对象所指向的 vector
}
/**
 * @brief 
 * 
 * @return StrBlobPtr& 
 */
StrBlobPtr& StrBlobPtr::incr()
{
    // 如果 curr 已经指向容器的尾后位置，就不能递增它
    check(curr, "increment past end of StrBlobPtr");
    ++curr; // 推进当前位置
    return *this;
}